/**
 * 
 */
package com.googlecode.xcarve.zk;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;

import com.googlecode.xcarve.common.config.CarveConstances;
import com.googlecode.xcarve.config.refer.NotifyListener;
import com.googlecode.xcarve.thread.DoveThreadFactory;

/**
 * @author duxinyun
 *
 */
public abstract class AbstractZkClient implements ZkClient{

	private final ScheduledExecutorService retryScheduled = Executors.newScheduledThreadPool(1, new DoveThreadFactory("register-scheduled-threadpool"));
	
	public AbstractZkClient() {
		retryScheduled.scheduleAtFixedRate(new Runnable() {
			
			@Override
			public void run() {
				retry();
			}
		}, CarveConstances.DEFAULT_IDLETIME_PERIOD, CarveConstances.DEFAULT_IDLETIME_PERIOD, TimeUnit.MILLISECONDS);
	}
	
	abstract void retry();

	public void createPath(String path){
		if(StringUtils.isBlank(path)){
			return;
		}
		createPersistent(path);
	}
	
	public void createPath(String path,boolean ephemeral){
		if(StringUtils.isBlank(path)){
			return;
		}
		int index = path.lastIndexOf("/");
		if(index > 0){
			createPath(path.substring(0, index), false);
		} 
		if(ephemeral){
			createEphemeral(path);
		}else{
			createPersistent(path);
		}
	}
	
	public void subscrible(final String path,final NotifyListener listener){
		if(StringUtils.isBlank(path)){
			return;
		}
		createPath(path, true);
		String subscriblePath = null;
		if(path.indexOf(CarveConstances.RPC_CONSUMER_NAME) != -1){
			subscriblePath = StringUtils.replace(path, CarveConstances.RPC_CONSUMER_NAME, CarveConstances.RPC_PROVIDER_NAME, 1);
		}else{
			return;
		}
		subscriblePath = StringUtils.substring(subscriblePath, 0, subscriblePath.lastIndexOf(CarveConstances.SEPTOR_PATH));
		doSubScrible(subscriblePath,listener);
	}
	
	abstract void createEphemeral(String path);
	
	abstract void createPersistent(String path);
	
	abstract void doSubScrible(final String path,final NotifyListener listener);
	
	@Override
	public void delete(String path) {
		
	}
	
}
